package com.creditease.rss.services;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.content.Context;
import android.util.Log;

import com.creditease.rss.RssConst;
import com.creditease.rss.dao.RssDB;
import com.creditease.rss.dao.RssItemDB;
import com.creditease.rss.model.RssItemModel;
import com.creditease.rss.model.RssModel;
import com.creditease.rss.util.FileUtil;
import com.creditease.rss.util.HttpUtils;
import com.creditease.rss.util.PicDownloadUtil;

import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ItemIF;
import de.nava.informa.core.ParseException;
import de.nava.informa.impl.basic.ChannelBuilder;
import de.nava.informa.parsers.FeedParser;

public class FeedServices {

	private RssItemDB itemdb;
	private RssDB db;
	private String TAG = FeedServices.class.getName();
	private static final String ROOT = RssConst.APPROOT;

	public FeedServices(Context context) {
		itemdb = new RssItemDB(context);
		db = new RssDB(context);
	}

	/**
	 * 刷新Rss内容，并保存到数据库 description
	 * 
	 * @param id
	 * @throws Exception
	 */
	public RssModel refrush(String id) throws Exception {
		String url = null;
		try {
			RssModel model = db.findById(id);
			url = model.url;
			if (url == null || "".equals(url)) {
				return null;
			}
			Log.d(TAG, "header=================");
			HttpResponse headers = HttpUtils.getHttpHead(url);
			Header header = headers.getFirstHeader("Last-Modified");
			Log.d(TAG, "header=" + header);

			if (model.pubDate != null && header != null) {
				Date lastUpDate = new Date(Long.valueOf(model.pubDate));
				String value = header.getValue();
				if (value != null && !"".equals(value)) {
					Date lastModified = new Date(value.trim());
					// 修改时间 更新时间 当且仅当此 Date 对象表示的瞬间比 when 表示的瞬间早，才返回 true；否则返回
					// false。
					boolean b = lastModified.before(lastUpDate);
					if (b) {
						long count = itemdb.countBySectionId(id);
						if (count > 0) {
							return null;
						}
					}
				}
			}
			String coder = model.enCode;
			if (coder == null || "null".equals(coder)) {
				coder = "UTF-8";
			}
			Log.d(TAG, "coder=" + coder);

			InputStream is = HttpUtils.getHttpStream(url);

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					is, coder));
			ChannelIF channel = FeedParser.parse(new ChannelBuilder(), reader);
			List<RssItemModel> items = itemdb.findBySectionId(id);
			Set<String> urlSet = new HashSet<String>();
			for (RssItemModel rss : items) {
				urlSet.add(rss.articleLink);
			}

			Set<ItemIF> list = channel.getItems();
			int index = 0;
			for (ItemIF b : list) {
				String link = b.getLink() == null ? "" : b.getLink().toString();
				// 如果数据库已经保存该文章，则跳过，不保存
				if (urlSet.contains(link)) {
					continue;
				}
				// 只有第一次触发
				if (index == 0) {
					model.desc = b.getTitle().trim();
					model.isRead = false;
					model.pubDate = new Date().getTime() + "";
					db.updateById(model);
				}
				index++;
				RssItemModel item = new RssItemModel();
				item.articleAuthorName = b.getCreator();
				item.articleLink = link;
				item.articleTitle = b.getTitle().trim();
				item.content = b.getDescription();
				item.isRead = false;
				item.isFav = false;
				item.time = new Date().getTime();
				item.articleTime = b.getDate() == null ? item.time : b
						.getDate().getTime();
				item.sectionId = id;
				itemdb.save(item);
				downloadImgs(b.getDescription());
			}
			return model;

		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("url :" + url + " valid");

		}

	}

	/**
	 * 根据url地址 添加Rss description
	 * 
	 * @param url
	 * @throws ParseException
	 * @throws Exception
	 */

	public void saveRss(RssDB db, String url) throws ParseException, Exception {

		RssModel model = new RssModel();
		try {
			String coder = getEnCode(url);
			Log.d(TAG, "coder=" + coder);

			InputStream is = HttpUtils.getHttpStream(url);
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					is, coder));
			ChannelIF channel = FeedParser.parse(new ChannelBuilder(), reader);
			model.title = channel.getTitle();
			model.url = url;
			model.desc = channel.getDescription();
			model.enCode = coder;
			model.pubDate = channel.getPubDate() == null ? "" : channel
					.getPubDate().toString(); // model.logoUrl
			// channel.getImage().getLink().toString();

			long id = db.save(model);
			Set<ItemIF> items = channel.getItems();
			int index = 0;
			for (ItemIF b : items) {
				// 只有第一次触发
				if (index == 0) {
					model.desc = b.getTitle().trim();
					model.isRead = false;
					model.pubDate = new Date().toString();
					db.updateById(model);
				}
				index++;
				String link = b.getLink() == null ? "" : b.getLink().toString();
				RssItemModel item = new RssItemModel();
				item.articleAuthorName = b.getCreator();
				item.articleLink = link;
				item.articleTitle = b.getTitle().trim();
				item.content = b.getDescription();
				item.isRead = false;
				item.isFav = false;
				item.time = new Date().getTime();
				item.articleTime = b.getDate() == null ? item.time : b
						.getDate().getTime();
				item.sectionId = id + "";
				itemdb.save(item);
				downloadImgs(b.getDescription());
			}
			reader.close();
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} catch (ParseException e) {
			e.printStackTrace();
			throw new com.creditease.rss.excetion.ParseException();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}

	}

	private void downloadImgs(String html) {

		if (html == null || "".equals(html.trim())) {
			return;
		}
		Document document = Jsoup.parse(html);
		Elements imgs = document.select("img[src]");
		// String path=RssConst.FILE_PREFIX+RssConst.PIC_TMP_DIR;
		for (Element ele : imgs) {
			String imgurl = ele.attr("src");
			String newFileName = FileUtil.getFileName(imgurl);
			// 后缀
			// ele.attr("src", path+newFileName);
			PicDownloadUtil.add2Queue(imgurl, RssConst.PIC_TMP_DIR
					+ newFileName);
		}
	}

	/**
	 * 备份Rss description
	 * 
	 * @return
	 * @throws IOException
	 */
	public boolean backupRss() throws IOException {

		List<RssModel> list = db.findAll();

		File file = new File(ROOT + File.separator + "RSS.bat");
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		OutputStream fos = new FileOutputStream(file);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		StringBuilder builder = new StringBuilder();
		for (RssModel model : list) {

			builder.append(model.url).append(",").append(model.title)
					.append(",").append(model.logoUrl).append(",")
					.append(model.enCode).append(",").append(model.desc)
					.append("\r\n");

		}
		Log.d(TAG, "backup data:");
		Log.d(TAG, builder.toString());
		bos.write(builder.toString().getBytes());
		bos.flush();
		bos.close();
		fos.close();
		return true;

	}

	/**
	 * 恢复Rss description
	 * 
	 * @return
	 * @throws IOException
	 */
	public boolean restoreRss() throws IOException {

		Reader fis = new FileReader(ROOT + File.separator + "RSS.bat");
		BufferedReader bis = new BufferedReader(fis);
		Map map = new HashMap();
		List<RssModel> list = db.findAll();
		for (RssModel model : list) {
			map.put(model.url, "");
		}
		String line = "";
		while ((line = bis.readLine()) != null) {
			String[] str = line.split(",");
			String url = str[0];
			if (map.containsKey(url)) {
				continue;
			}
			RssModel model = new RssModel();
			model.url = url;
			model.title = str[1];
			model.logoUrl = str[2];
			model.enCode = str[3] == null ? "UTF-8" : str[3];
			if (str.length > 4) {
				model.desc = str[4];
			}
			db.save(model);
		}
		bis.close();
		fis.close();
		return true;
	}

	private String getEnCode(String url) throws Exception {
		String coder = null;

		InputStream is = HttpUtils.getHttpStream(url);
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		// 第一行 <?xml version="1.0" encoding="gb2312"?><rss version="2.0">
		String tmp = "encoding=\"";
		String line = reader.readLine();
		String rss = line.substring(line.indexOf(tmp) + tmp.length());
		coder = rss.substring(0, rss.indexOf("\""));
		reader.close();
		is.close();

		if (coder != null && coder.equalsIgnoreCase("gb2312")) {
			coder = "GBK";
		}

		return coder;

	}
}
